package String

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Sort"
	"reflect"
)

func buildIMap(data map[string]interface{}) map[interface{}]interface{} {
	result := make(map[interface{}]interface{})
	for key, val := range data {
		result[key] = val
	}
	return result
}

func GetMapString(data interface{}) string {
	keys := getMapKeys(data)

	Sort.Sort(keys, func(key1, key2 interface{}) bool {
		str1 := makeString(key1)
		str2 := makeString(key2)

		return str1 < str2
	})

	str := "["
	for _, key := range keys {
		value := getMapValue(data, key)

		str += ToString(key)
		str += "="

		if reflect.TypeOf(value).Kind() == reflect.Map {
			str += GetMapString(value)
		} else if reflect.TypeOf(value).Kind() == reflect.Slice {
			str += GetSliceString(value)
		} else {
			str += ToString(value)
		}

		str += ","
	}

	if len(str) > 1 {
		str = str[:len(str)-1]
	}
	str += "]"

	return str
}

func getMapKeys(data interface{}) []interface{} {
	mValue := reflect.ValueOf(data)
	keys := make([]interface{}, 0, mValue.Len())

	for _, keyValue := range mValue.MapKeys() {
		keys = append(keys, keyValue.Interface())
	}

	return keys
}

func GetSliceString(array interface{}) string {
	Sort.Sort(array, func(key1, key2 interface{}) bool {
		str1 := makeString(key1)
		str2 := makeString(key2)
		return str1 < str2
	})

	list := reflect.ValueOf(array)

	str := ""
	for i := 0; i < list.Len(); i++ {
		value := list.Index(i).Interface()

		if reflect.TypeOf(value).Kind() == reflect.Map {
			str += GetMapString(value)
		} else if reflect.TypeOf(value).Kind() == reflect.Slice {
			str += GetSliceString(value)
		} else {
			str += ToString(value)
		}
		str += ","
	}

	if len(str) > 1 {
		str = str[:len(str)-1]
	}

	return str
}

func getMapValue(data interface{}, key interface{}) interface{} {
	v := reflect.ValueOf(data)

	mv := v.MapIndex(reflect.ValueOf(key))
	return mv.Interface()
}

func makeString(value interface{}) string {
	if reflect.TypeOf(value).Kind() == reflect.Map {
		return GetMapString(value)
	} else if reflect.TypeOf(value).Kind() == reflect.Slice {
		return GetSliceString(value)
	} else {
		return ToString(value)
	}
}
